import Web3 from "web3"
import abi from "./abi.js"
import BigNumber from "bignumber.js";

/**
 * 合约地址
 */
export const contractAddress = '0x55d398326f99059fF775485246999027B3197955'

/**
 * 判断系统源 是ios 还是安卓
 */
export const appSource = () => {
	const u = navigator.userAgent;
	const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
	if (isiOS) {
		return "ios";
	} else {
		return "andriod";
	}
}


/**
 * 科学技术法转换
 */
export const scientificToNumber = async (inputNumber) => {
	const web3 = new Web3(window.ethereum);
	return await new web3.utils.toBN(inputNumber)
	// if (isNaN(inputNumber)) {
	// 	return inputNumber
	// }
	// inputNumber = '' + inputNumber
	// inputNumber = parseFloat(inputNumber)
	// let eformat = inputNumber.toExponential() // 转换为标准的科学计数法形式（字符串）
	// let tmpArray = eformat.match(/\d(?:\.(\d*))?e([+-]\d+)/) // 分离出小数值和指数值
	// let number = inputNumber.toFixed(Math.max(0, (tmpArray[1] || '').length - tmpArray[2]))

}



/**
 * 补齐64位，不够前面用0补齐
 * @param {*} num 
 * @returns 
 */
export const addPreZero = (num) => {
	var t = (num + '').length,
		s = '';
	for (var i = 0; i < 64 - t; i++) {
		s += '0';
	}
	return s + num;
}


/**
 *  获取账户信息
 */
export const getAccounts = async () => {
	return new Promise(async (resolve, reject) => {
		const web3 = new Web3(window.ethereum);
		let fromAddress = await new web3.eth.getAccounts()
		resolve(fromAddress[0])
	});
}

/**
 * 获取余额
 */
export const getBalance = async (address) => {
	return new Promise(async (resolve, reject) => {
		const web3 = new Web3(window.ethereum);
		const balance = await new web3.eth.getBalance(address, (err, res) => {
			if (!err) {
				resolve(res / Math.pow(10, 18))
			}
		})
	});
}

/**
 * 获取代币余额
 */
export const getTokenBalance = async (walletAddress, contractAddress) => {
	return new Promise(async (resolve, reject) => {
		const data = "0x70a08231" + "000000000000000000000000" + walletAddress.split("0x")[1]
		window.ethereum
			.request({
				"jsonrpc": "2.0",
				method: 'eth_call',
				params: [{
					from: walletAddress,
					to: contractAddress,
					data
				}, "latest"],
				"id": 1
			}).then((res) => {
				resolve(res / Math.pow(10, 18))
			})
			.catch((error) => {
				reject(error)
			});
	});
}





/**
 *  初始化
 */
export const init = async (web3Entity) => {
	return new Promise((resolve, reject) => {
		//初始化过程
		if (typeof web3Entity !== 'undefined') {
			const web3 = new Web3(web3.currentProvider);
			resolve(web3)
		} else {
			const web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"));
			resolve(web3)
		}
	});
}

/**
 *  初始化Abi
 */
export const initAbi = async (collection) => {
	return new Promise((resolve, reject) => {
		const web3 = new Web3(window.ethereum);
		const web3Abi = new web3.eth.Contract(abi, collection);
		if (web3Abi) {
			resolve(web3Abi)
		} else {
			reject()
		}
	});
}

/**
 * 获取动态 Price
 */
export const getGasPrice = async () => {
	return new Promise((resolve, reject) => {
		const web3 = new Web3(window.ethereum);
		const gasPrice = new web3.eth.getGasPrice()
		resolve(gasPrice)
	});
}

/**
 * 动态获取 GasLimit
 */
export const getGasLimit = async ({
	contract,
	amount,
	from,
	to
}) => {
	return new Promise(async (resolve, reject) => {
		const web3 = new Web3(window.ethereum);
		const _amount = new BigNumber(amount).times(Math.pow(10, 18))
		const type = 'a9059cbb'
		const data = '0x' + type + addPreZero(to.substr(2)) + addPreZero(_amount.toString(16))
		const gasPrice = await getGasPrice()
		const transactionObject = {
			from, //当前地址
			to: contract, ///合约地址
			gasPrice,
			value: "0x0",
			data
		}
		const gasLimit = await new web3.eth.estimateGas(transactionObject);
		resolve(gasLimit)
	});
}
/**
 *  发送
 * methodName 方法名称
 * from 钱包地址
 * to  收款地址
 * amount 收款数量
 */
export const send = async ({
	from,
	methodName,
	to,
	amount,
	gasPrice,
	gasLimit,
	entity
}) => {
	return new Promise(async (resolve, reject) => {
		// console.log("已经进入支付-封装函数执行前");
		const web3 = new Web3(window.ethereum);
		gasPrice = gasPrice ? gasPrice : await getGasPrice()
		gasLimit = gasLimit ? gasLimit : await getGasLimit({
			contract: contractAddress,
			amount,
			from,
			to
		})
		let obj = {
			from,
			gasPrice,
			gasLimit
		}

		// console.log("已经进入支付-封装函数执行前-马上进入");
		entity.methods[methodName](to, amount).send({
			...obj,
		}).on('receipt', (res) => {
			// console.log("已经进入支付-封装函数执行-成功反馈");
			resolve(res)
		}).on('error', (error) => {
			// console.log(error);
			// console.log("已经进入支付-封装函数执行-失败反馈");
			reject(error)
		})
	});
}